﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Commands;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Tests.Integration.Instruments;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Views;
using System.Diagnostics;
using System.IO;
using System.Linq;
using White.Core;
using White.Core.Factory;
using White.Core.UIItems;
using White.Core.UIItems.Finders;
using WPF = System.Windows.Controls;
using White.Core.UIItems.TreeItems;
using System.Threading;
using System.Collections.Generic;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Tests.Integration.Commands
{
    public abstract class CommandTestAutomaterBase<TCommand> : FxCopIntegratorTestAutomaterBase
        where TCommand : ICommand
    {
        protected abstract string SolutionRelativePath { get; }

        protected abstract string[] SolutionItemsToInspect { get; }

        protected abstract string[] ExpectedCheckIds { get; }


        protected void ExecuteShouldShowWarnings()
        {
            RunOnUIThread(() =>
            {
                Assert.WindowPaneDoesNotExist<CodeInspectionResultWindowPane>();
                Assert.WindowPaneDoesNotExist<CodeMetricsCalculationResultWindowPane>();

                OpenSolution(SolutionRelativePath);
                SelectSolutionItem(SolutionItemsToInspect);
                ExecuteCommand<TCommand>();

                Assert.WindowPaneExists<CodeInspectionResultWindowPane>();
                Assert.WindowPaneDoesNotExist<CodeMetricsCalculationResultWindowPane>();

                var windowPane = GetWindow<CodeInspectionResultWindowPane>();
                var dataGrid = windowPane.Get<WPF.DataGrid>("resultDataGrid");
                Assert.CollectionsAreEqual(ExpectedCheckIds, dataGrid.Items.Cast<ProblemViewModel>().Select(o => o.CheckId));
            });
        }

        protected void ExecuteShouldShowMessageBoxWhenFxCopCmdPathIsNotValid()
        {
            Package.GeneralOption.FxCopCmdPath = "invalid.exe";

            RunOnUIThread(() =>
            {
                OpenSolution(SolutionRelativePath);
                SelectSolutionItem(SolutionItemsToInspect);
                ExecuteCommand<InspectProjectCommand>(new UIControlAction(2000, () =>
                {
                    var application = Application.Attach(Process.GetCurrentProcess());
                    var window = application.Find(o => o == "solution - Microsoft Visual Studio - Experimental Instance", InitializeOption.NoCache);
                    var msgBox = window.MessageBox("Warning");
                    var button = msgBox.Get<Button>(SearchCriteria.ByText("OK"));
                    button.RaiseClickEvent();
                }));
            });

            Thread.Sleep(2000);

            RunOnUIThread(() =>
            {
                var application = Application.Attach(Process.GetCurrentProcess());
                var window = application.Find(o => o == "Options", InitializeOption.NoCache);
                var tree = window.Get<Tree>();
                var node = tree.SelectedNode;
                Assert.ObjectsAreEqual("General", node.Text);
                window.Close();
            });
        }
    }
}
